<?php
/**
 * PsiFramework
 *
 * Php Simple Framework
 *
 * PHP version 5.3
 *
 * @category  PsiFramework.Plugins.Form.Classes.Util.Json
 * @package   PsiFramework.Plugins.Form.Classes.Util
 * @author    Remi San <remi.san@gmail.com>
 * @copyright 2011 Remi San
 * @license   http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @version   SVN: <svn_id>
 * @link      http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\Util\FormUtil.html
 */

namespace PsiFramework\Plugins\Form\Classes\Util;

use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;
use \PsiFramework\Classes\Factory\DAOFactory;
use \PsiFramework\Classes\Util\UI\LanguageManager;
use \PsiFramework\Classes\Util\UI\TemplateManager;
use \PsiFramework\Classes\Util\UI\Printer;
use \PsiFramework\Classes\Util\Parameters\ObjectParameters;
use \PsiFramework\Plugins\Form\Classes\DAO\FormResponseDAO;
use \PsiFramework\Plugins\Form\Classes\Util\Json\JsonForm;
use \PsiFramework\Plugins\Form\Classes\Util\Json\JsonFormElement;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormInput;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormText;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormTitle;

/**
 * The Form Utility class
 *
 * This is the form utility class
 *
 * @category PsiFramework.Plugins.Form.Classes.Util.Json
 * @package  PsiFramework.Plugins.Form.Classes.Util
 * @author   Remi San <remi.san@gmail.com>
 * @license  http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @link     http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\Util\FormUtil.html
 */
class FormUtil
{
    /**
     * The function that returns a label
     * 
     * @param mixed $value The label
     * 
     * @return string
     */
    protected static function getLabel(/*mixed*/ $value)
    {
        return Printer::getText(
            LanguageManager::getInstance()->getText($value)
        );
    }

    /**
     * The function that returns a block
     *
     * @param mixed $value The block
     *
     * @return string
     */
    protected static function getBlock(/*mixed*/ $value)
    {
        return Printer::getText(
            LanguageManager::getInstance()->getText($value)
        );
    }

    /**
     * The function that displays the form response values
     * 
     * @param JsonForm         $form               The form
     * @param ObjectParameters $responseParameters The object parameters
     * @param FormResponse     $response           The response
     * 
     * @return string
     */
    public static function showFormValues(
        JsonForm         $form,
        ObjectParameters $responseParameters,
        /*FormResponse*/ $response=null
    )
    {
        $elements = $form->getElements();
        $formString = '' ;
        
        if (!is_null($elements) && !is_null($response)) {
            
            $formResponseDao = FormResponseDAO::getInstance($responseParameters);
            
            if (!$formResponseDao->isEmpty(
        		$form,
        		$responseParameters,
        		$response
            )
            ) {
                foreach ($elements as $field) {
                    $allElements = '' ;
                    
                    $atLeastOneresponse = false ;
                    $onlyText = true ;
                    
                    foreach ($field->getElements() as $element) {
                        $inputElement = '' ;
    
                        if ($element instanceof JsonFormInput) {
    
                            $onlyText = false ;
                            
                            $value = null ;
                            if (!is_null($response)) {
                                $param = $responseParameters->getParameter(
                                    $element->getName()
                                );
                                if (!is_null($param)) {
                                    $getter = $param->getter ;
                                    $value = $response->{$getter}();
                                }
                            }
                            if (!is_null($value)
                                && $element->getInputType() == 'checkbox'
                            ) {
                                if (strpos($value, ',')>0) {
                                    $value = preg_split("[,]", $value);
                                }
                            }
                            if (!isNullOrEmptyString($value)) {
                                $inputElement = self::getInputValue(
                                    $element,
                                    $value
                                );
                                
                                $atLeastOneresponse = true ;
                            }
    
                        } else {
                            if ($element->isDisplayedWithValues()) {
                                if ($element instanceof JsonFormText) {
                                    $inputElement = self::getText($element);
                                } else if ($element instanceof JsonFormTitle) {
                                    $inputElement = self::getTitle($element);
                                } else {
                                    $inputElement = self::getClearBoth($element);
                                }
                            }
                        }
                        
                        if (!isNullOrEmptyString($inputElement)) {
                            $allElements .= $inputElement.' ' ;
                        }
                    }

                    if (!isNullOrEmptyString($allElements) && ($onlyText || $atLeastOneresponse)) {
                        $formString .= '<li class="element">'.$allElements.'</li>' ;
                    }
                }
            }
        }
        
        return $formString;
    }

    /**
     * The function that displays the form
     * 
     * @param JsonForm         $form               The form
     * @param ObjectParameters $responseParameters The response parameters
     * @param FormResponse     $response           The form response
     * @param bool             $editable           Is the form editable ?
     * 
     * @return void
     */
    public static function showForm(
        JsonForm         $form,
        ObjectParameters $responseParameters,
        /*FormResponse*/ $response=null,
        /*bool*/         $editable=true
    )
    {
        $elements = $form->getElements();

        TemplateManager::getInstance()->addLitteralScript(
    		"
            function processGroupElements(groupName) {
                var alreadyOne = false;
                $('.'+groupName).each(function(index, element) {
                    if($(element).hasClass('hideGroup')){
                        $(element).hide();
                        var previous = $(element).prev();
                        if(previous != null){
                            if(previous.hasClass('showGroup') && !alreadyOne){
                                var buttonTitle = getElementTitle($(element));
                                previous.append(getAddButton(groupName, buttonTitle));
                                alreadyOne = true;
                            }
                        }
                    }
                });
            }
            
            function getElementTitle(parentElement) {
                var details = parentElement.find('.showMoreTitle');
                return details.text();
            }
                
            function getAddButton(groupName, buttonTitle) {
                if (buttonTitle === undefined || buttonTitle == null || buttonTitle == '') buttonTitle = '+';
                return '<input type=\"button\" class=\"addButton\" value=\"'+buttonTitle+'\" onclick=\"javascript:showGroupElement(\''+groupName+'\', this)\" />';
            }
                
            function showGroupElement(groupName, element) {
                var parent = $(element).parent();
                $(element).remove();
                
                var next = parent.next();
                if(next!=null){
                    var nextNext = next.next();
                    
                    while(nextNext!=null && nextNext.hasClass(groupName)){
                        if(nextNext.hasClass('hideGroup')){
                            break;
                        }
                        nextNext = nextNext.next();
                    }
                
                    if(nextNext!=null && nextNext.hasClass(groupName)){
                        var buttonTitle = getElementTitle(nextNext);
                        nextNext.prev().append(getAddButton(groupName, buttonTitle));
                    }
                    next.show();
                }
            }
            "
        );
        
        $allFields = '' ;

        if (!is_null($elements) && count($elements)>0) {
            
            $previousMetaGroupName = null;
            
            foreach ($elements as $field) {
                
                $metaclass = 'typeLeft' ;
                if (!isNullOrEmptyString($field->getClass())) {
                    $metaclass .= ' ' . $field->getClass();
                }
                
                $metastyles = '' ;
                if (!isNullOrEmptyString($field->getStyle())) {
                	$metastyles .= ' style="' . $field->getStyle() .'"';
                }
                
                $previousGroupName = null;
                
                $fieldSetContent = '';
                $hasNonEmptyValue = false;
                foreach ($field->getElements() as $element) {

                    $inputElement = '' ;

                    if ($element instanceof JsonFormInput) {

                        $value = null ;
                        if (!is_null($response)) {
                            $param = $responseParameters->getParameter(
                                $element->getName()
                            );
                            if (!is_null($param)) {
                                $getter = $param->getter ;
                                $value = $response->{$getter}();
                            }
                        }

                        switch($element->getInputType()) {
                        case 'text' :
                            $inputElement = self::getTextInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        case 'hour' :
                        	$inputElement = self::getHourInput(
                            	$element,
                            	$value,
                            	$editable
                        	);
                        	break ;
                        case 'date' :
                            $inputElement = self::getDateInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        case 'file' :
                            $inputElement = self::getFileInput(
                            	$element,
                            	$value,
                                $editable
                        	);
                            break ;
                        case 'textarea' :
                            $inputElement = self::getTextareaInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        case 'radio' :
                            $inputElement = self::getRadioInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        case 'checkbox' :
                            if (strpos($value, ',')>0) {
                                $value = preg_split("[,]", $value);
                            }
                            $inputElement = self::getCheckboxInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        case 'select' :
                            $inputElement = self::getSelectInput(
                                $element,
                                $value,
                                $editable
                            );
                            break ;
                        }

                        $class = '' ;
                        if ($element->isMandatory()) {
                            $class= 'required' ;
                        }
                        
                        if (!isNullOrEmptyString($element->getClassName())) {
                            if (!isNullOrEmptyString($class)) {
                                $class .= ' ' ;
                            }
                            $class .= $element->getClassName();
                        }
                        
                        $style = $element->getStyle();

                        if (!isNullOrEmptyString($value)) {
                            $hasNonEmptyValue = true;
                        }
                        
                        $currentGroupName = $element->getGroup();
                        if (!isNullOrEmptyString($currentGroupName)) {
                            $groupClassName = 'group_'.$currentGroupName;
                            $class .= ' '.$groupClassName;
                            if ($currentGroupName==$previousGroupName
                                && isNullOrEmptyString($value)
                            ) {
                            	$class .= ' hideGroup';
                            } else {
                                $class .= ' showGroup';
                            }
                            
                            TemplateManager::getInstance()->addLitteralScript(
                        		"
                                $(document).ready(function(){
                        			processGroupElements('".$groupClassName."');
                        		});
                                "
                            );
                        }
                        
                        if (!isNullOrEmptyString($class)) {
                        	$class = 'class="'.$class.'"' ;
                        }
                        
                        if (!isNullOrEmptyString($style)) {
                            $style = 'style="'.$style.'"' ;
                        }
                        
                        $inputElement
                            = '<span '.$class.' '.$style.' >' . 
                                  $inputElement .
                              '</span>' ;
                        
                    } else if ($element instanceof JsonFormText) {
                        $inputElement = self::getText($element);
                    } else if ($element instanceof JsonFormTitle) {
                        $inputElement = self::getTitle($element);
                    } else {
                        $inputElement = self::getClearBoth($element);
                    }

                    $fieldSetContent .= $inputElement ;
                    
                    $previousGroupName = $element->getGroup();
                }
                
                $currentMetaGroup = $field->getGroup();
                $currentMetaGroupName = null;
                $currentMetaGroupTitle = '';
                if (!isNullOrEmptyString($currentMetaGroup)) {
                    $currentMetaGroupName = $currentMetaGroup->name;
                    $currentMetaGroupTitle = $currentMetaGroup->title;
                    if (isNullOrEmptyString($currentMetaGroupTitle)) {
                        $currentMetaGroupTitle = '+';
                    }
                    if (!isNullOrEmptyString($currentMetaGroupName)) {
                    	$metagroupClassName = 'metagroup_'.$currentMetaGroupName;
                    	$metaclass .= ' '.$metagroupClassName;
                    	if ($currentMetaGroupName==$previousMetaGroupName
                			&& !$hasNonEmptyValue
                    	) {
                    		$metaclass .= ' hideGroup';
                    	} else {
                    		$metaclass .= ' showGroup';
                    	}
                    
                    	TemplateManager::getInstance()->addLitteralScript(
                			"
                			$(document).ready(function(){
                			    processGroupElements('".$metagroupClassName."');
                            });
                			"
                    	);
                    }
                }
                $previousMetaGroupName = $currentMetaGroupName;
                
                $fieldName = $field->getName();
                $allFields .= '<fieldset' ;
                $allFields .= ' class="'.$metaclass.'"' ;
                $allFields .= $metastyles ;
                $allFields .= ' id="field_'.$fieldName.'"' ;
                $allFields .= ' >' ;
                
                $allFields .=     '<details class="showMoreTitle" style="display:none;">'.$currentMetaGroupTitle.'</details>' ;
                $allFields .=     $fieldSetContent;
                
                $allFields .= '</fieldset>' ;
            }
        }

        return $allFields ;
    }

    /**
     * The function that resturns the code to edit the json form
     * 
     * @param JsonForm $form The form
     * 
     * @return string
     */
    public static function showForEditFieldType(JsonForm $form)
    {

        $js = '' ;
        $elements = $form->getElements();

        if (!is_null($elements) && count($elements)==1) {
            $field = $form->getElement(0);
            
            $js .= "    fieldTypeCreatorClass.value = '".$field->getClass()."' ;\n" ;
            $js .= "    fieldTypeCreatorStyle.value = '".$field->getStyle()."' ;\n" ;
            
            foreach ($field->getElements() as $element) {

                $inputElement = '' ;
                $type = '' ;

                $parameters = new \stdClass();
                $parameters->label = $element->getLabel();
                $parameters->style
                    = (is_null($element->getStyle()))?
                        '':$element->getStyle();
                $parameters->className
                    = (is_null($element->getClassName()))?
                        '':$element->getClassName();
                $parameters->displayWithValues
                    = (is_null($element->isDisplayedWithValues()))?
                        '':$element->isDisplayedWithValues();
                $parameters->group
                    = (is_null($element->getGroup()))?
                        '':$element->getGroup();

                if ($element instanceof JsonFormInput) {
                    $parameters->name
                        = (is_null($element->getName()))?
                            '':$element->getName();
                    $parameters->defaultValue
                        = (is_null($element->getValue()))?
                            '':$element->getValue();
                    $parameters->mandatory = $element->isMandatory();
                    $parameters->string = $element->isString();
                    $parameters->numeric = $element->isNumeric();
                    $parameters->float = $element->isFloat();
                    $parameters->displayAsImage = $element->isDisplayedAsImage();
                    $parameters->minLength
                        = (is_null($element->getMinLength()))?
                            '':$element->getMinLength();
                    $parameters->maxLength
                        = (is_null($element->getMaxLength()))?
                            '':$element->getMaxLength();
                    $parameters->image
                        = (isNullOrEmptyString($element->isImage()))?
                            false:$element->isImage();
                    $parameters->imageWidth
                        = (isNullOrEmptyString($element->getImageWidth()))?
                            '':$element->getImageWidth();
                    $parameters->imageHeight
                        = (isNullOrEmptyString($element->getImageHeight()))?
                            '':$element->getImageHeight();
                    $type = $element->getInputType();

                    $options = null ;
                    if (!is_null($element->getOptions())
                        && count($element->getOptions())>0
                    ) {
                        $options = array();
                        foreach ($element->getOptions() as $option) {
                            $paramOption = new \stdClass();
                            $paramOption->value = $option->getValue();
                            $paramOption->selected = $option->isSelected();

                            $options[] = $paramOption ;
                        }
                    }
                    $parameters->options = $options ;
                } else if ($element instanceof JsonFormText) {
                    $type = 'p' ;
                } else if ($element instanceof JsonFormTitle) {
                    $type = 'title' ;
                } else {
                    $type = 'clear-both' ;
                }

                $js .= "    fieldTypeCreatorElements.appendChild(".
                                "createLi(".
                                    "createFormElement(".
                                        "'".$type."', ".
                                        json_encode($parameters).
                                    ")".
                                ")".
                            ");\n" ;

            }
        }

        return $js ;
    }

    /**
     * The function that returns a text input
     * 
     * @param JsonFormInput $element  the text input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     * 
     * @return string
     */
    public static function getTextInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {
        $class = 'responseValue' ;
        $required = '' ;
        if ($element->isMandatory()) {
            $class .= ' required' ; $required = 'required="required"' ;
        }
        if ($element->isNumeric()) {
            $class .= ' digits' ;
        }
        if ($element->isFloat()) {
            $class .= ' number' ;
        }

        $inputElement  = '<label '.
                              'class="formlabel" '.
                              'for="'.Printer::getText($element->getName()).'"'.
                          '>'.
                              self::getLabel($element->getLabel()).
                         '</label>'.
                         '<input '.
                             'type="text" '.
                             'id="'.Printer::getText(
                                 $element->getName()
                             ).'" '.
                             'name="'.Printer::getText(
                                 $element->getName()
                             ).'" ' ;
        if (!$editable) {
            $inputElement .= 'disabled="disabled" ' ;
        }
        
        $inputElement .=     'class="'.$class.'" '.
                             $required . ' ' ;
        if (!isNullOrEmptyString($element->getMinLength())) {
            $inputElement .= 'minlength="'.$element->getMinLength().'" ' ;
        }
        if (!isNullOrEmptyString($element->getMaxLength())) {
            $inputElement .= 'maxlength="'.$element->getMaxLength().'" ' ;
        }

        $inputElement .= 'value="'.Printer::getText($value).'"/>' ;

        return $inputElement ;
    }
    
    /**
     * The function that returns a hour input
     *
     * @param JsonFormInput $element  the hour input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getHourInput(
		JsonFormInput $element,
		/*mixed*/     $value=null,
		/*bool*/      $editable=true
    )
    {
    	$class = 'responseValue' ;
    	$required = '' ;
    	if ($element->isMandatory()) {
    		$class .= ' required' ; $required = 'required="required"' ;
    	}
    	if ($element->isNumeric()) {
    		$class .= ' digits' ;
    	}
    	if ($element->isFloat()) {
    		$class .= ' number' ;
    	}
    
    	$inputElement  = '<label '.
    			'class="formlabel" '.
    			'for="'.Printer::getText($element->getName()).'"'.
    			'>'.
    			self::getLabel($element->getLabel()).
    			'</label>'.
    			'<select '.
    			'id="'.Printer::getText(
					$element->getName()
    			).'" '.
    			'name="'.Printer::getText(
					$element->getName()
    			).'" ' ;
    	if (!$editable) {
    		$inputElement .= 'disabled="disabled" ' ;
    	}
    
    	$minutesArray = array ('00', '15', '30', '45'); 
    	
    	$inputElement .= 'class="'.$class.'" '.$required.' >' ;
    	$inputElement .= '<option value=""></option>';
        for ($hour=0; $hour<24; $hour++) {
            $sHour = $hour;
            if ($hour<10) {
                $sHour = '0'.$hour;
            }
            
            foreach ($minutesArray as $minute) {
                $hourMinute = $sHour.':'.$minute;
                $selected = '';
                if ($hourMinute == $value) {
                    $selected = 'selected="selected" ';
                }
                $inputElement .= '<option value="'.$hourMinute.'" '.$selected.'>'.$hourMinute.'</option>'."\n";
            }
        }
    	$inputElement .= '</select>' ;
    
    	return $inputElement ;
    }
    

    /**
     * The function that returns a date input
     *
     * @param JsonFormInput $element  the date input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getDateInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {
        $inputElement  = '<label '.
                              'class="formlabel" '.
                              'for="'.Printer::getText($element->getName()).'"'.
                          '>'.
                              self::getLabel($element->getLabel()).
                         '</label>';
        $inputElement .= '<input '.
                            'type="date" '.
                            'id="'.Printer::getText($element->getName()).'" '.
                            'name="'.Printer::getText($element->getName()).'" ' ;
        if (!$editable) {
            $inputElement .= 'disabled="disabled" ' ;
        }
        
        $inputElement .=    'class="responseValue '.
                                LanguageManager::getInstance()->
                                getLanguage().'Date '.
                                'psiDate" '.
                            'value="'.Printer::getText($value).'" '.
                          '/>' ;

        return $inputElement ;
    }
    
    /**
     * The function that returns a file input
     * 
     * @param JsonFormInput $element  the file input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     * 
     * @return string
     */
    public static function getFileInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {
    	$inputElement  = '<label '.
    			'class="formlabel" '.
    			'for="'.Printer::getText($element->getName()).'"'.
    			'>'.
    			self::getLabel($element->getLabel()).
    			'</label>';
    	$inputElement .= '<input '.
    			'type="file" '.
    			'id="'.Printer::getText($element->getName()).'" '.
    			'name="'.Printer::getText($element->getName()).'" ' ;
        if (!$editable) {
            $inputElement .= 'disabled="disabled" ' ;
        }
        
        $inputElement .= 'class="responseValue" '.
    			'value="" '.
    			'/>' ;
    
    	if (!is_null($value)) {
    	    $filePath = $value->serialize();
    	    if (!isNullOrEmptyString($filePath)) {
    	        if ($element->isImage()) {
    	            $realPath = str_replace(getWwwDirectory().'/', '', realpath($filePath));
    	            $inputElement .= '<img src="'.Printer::getText($realPath).'" width="100" />' ;
    	        } else {
    	            $inputElement .= '<span class="presentFile">'.Printer::getText(basename($filePath)).'</span>' ;
    	        }
    	        $inputElement .= '<input '.
    	       	    'type="hidden" '.
    	       	    'name="current_'.Printer::getText($element->getName()).'" '.
    	       	    'value="'.Printer::getText($filePath).'" />' ;
    	        $inputElement .= '<label>'.
    	       	        '<input '.
        	        		'type="checkbox" '.
        	        		'name="delete_'.Printer::getText($element->getName()).'" ' ;
                if (!$editable) {
                    $inputElement
                        .=  'disabled="disabled" ' ;
                }
        
                $inputElement
                    .=      'value="'.Printer::getText($filePath).'" />'.
    	        		'Supprimer'.
	        		'</label>' ;
    	    }
    	}
    	
    	return $inputElement ;
    }

    /**
     * The function that returns a textarea input
     *
     * @param JsonFormInput $element  the textarea input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getTextareaInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {
        $required = '' ;
        $class = '' ;
        if ($element->isMandatory()) {
            $class .= ' required' ; $required = 'required="required"' ;
        }

        $inputElement  = '<label '.
                            'class="formlabel" '.
                            'for="'.Printer::getText($element->getName()).'"'.
                            '>'.
                              self::getLabel($element->getLabel()).
                         '</label>' ;
        $inputElement .= '<textarea '.
                             'id="'.Printer::getText(
                                 $element->getName()
                             ).'" '.
                             'name="'.Printer::getText(
                                 $element->getName()
                             ).'" '.
                             'class="responseValue'.$class.'" ' ;
        if (!$editable) {
            $inputElement .= 'disabled="disabled" ' ;
        }
        
        if (!isNullOrEmptyString($element->getMinLength())) {
            $inputElement .= 'minlength="'.$element->getMinLength().'" ' ;
        }
        if (!isNullOrEmptyString($element->getMaxLength())) {
            $inputElement .= 'maxlength="'.$element->getMaxLength().'" ' ;
        }
        
        $inputElement .= $required . ' ' ;
        $inputElement .= '>'.Printer::getText($value, false).'</textarea>' ;

        return $inputElement ;
    }

    /**
     * The function that returns a radio input
     *
     * @param JsonFormInput $element  the radio input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getRadioInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {

        $inputElement  =         '<label class="formlabel">' ;
        $inputElement .=              self::getLabel($element->getLabel());
        $inputElement .=         '</label>' ;
        $inputElement .=         '<ul>' ;

        foreach ($element->getOptions() as $option) {

            $checked = '' ;
            if ((is_null($value) && $option->isSelected())
                || $option->getValue() === $value
            ) {
                $checked = 'checked="checked"' ;
            }
            $name = $element->getName();

            $inputElement .=        '<li>'.
                                         '<label>'.
                                             '<input '.
                                                  'type="radio" '.
                                                  'name="'.Printer::getText(
                                                      $name
                                                  ).'" '.
                                                  'value="'.Printer::getText(
                                                      $option->getValue()
                                                  ).'" '.
                                                  'class="defaulValue" ' ;
            if (!$editable) {
                $inputElement .=                  'disabled="disabled" ' ;
            }
        
            $inputElement .=                       $checked.' '.
                                             '/>'.
                                             '<span>'.
                                                Printer::getText(
                                                    LanguageManager::getInstance()
                                                    ->getText(
                                                        $option->getValue()
                                                    )
                                                ).
                                             '</span>'.
                                         '</label>'.
                                     '</li>' ;
        }
        $inputElement .=         '</ul>' ;

        return $inputElement ;
    }

    /**
     * The function that returns a checkbox input
     *
     * @param JsonFormInput $element  the checkbox input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getCheckboxInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {

        $inputElement  =         '<label class="formlabel">' ;
        $inputElement .=              self::getLabel($element->getLabel());
        $inputElement .=         '</label>' ;
        $inputElement .=         '<ul>' ;
        foreach ($element->getOptions() as $option) {

            $checked = false ;
            if ((is_null($value) && $option->isSelected())
                || (!is_array($value) && $option->getValue() === $value)
            ) {
                $checked = true ;
            } else if (!is_null($value) && is_array($value)) {
                foreach ($value as $val) {
                    if ($option->getValue() === $val) {
                        $checked = true ;
                        break;
                    }
                }
            }
            if ($checked) {
                $checked = 'checked="checked"' ;
            }
            $name = $element->getName().'[]' ;

            $inputElement .= '<li>'.
                                 '<label>'.
                                     '<input '.
                                         'type="checkbox" '.
                                         'name="'.Printer::getText($name).'" '.
                                         'value="'.Printer::getText(
                                             $option->getValue()
                                         ).'" ' ;
            if (!$editable) {
                $inputElement .=         'disabled="disabled" ' ;
            }
            
            $inputElement .=             'class="defaulValue" '.$checked.' '.
                                     '/>'.
                                     '<span>'.
                                         Printer::getText(
                                             LanguageManager::getInstance()->
                                             getText(
                                                 $option->getValue()
                                             )
                                         ).
                                     '</span>'.
                                 '</label>'.
                             '</li>' ;
        }
        $inputElement .= '</ul>' ;

        return $inputElement ;
    }

    /**
     * The function that returns a select input
     *
     * @param JsonFormInput $element  the select input element
     * @param mixed         $value    the value of the input
     * @param bool          $editable is the the value editable ?
     *
     * @return string
     */
    public static function getSelectInput(
        JsonFormInput $element,
        /*mixed*/     $value=null,
        /*bool*/      $editable=true
    )
    {
        $name = $element->getName();

        $inputElement  = '<label '.
                              'class="formlabel" '.
                              'for="'.Printer::getText($element->getName()).'"'.
                          '>'.
                              self::getLabel($element->getLabel()).
                         '</label>' ;

        $inputElement .= '<select '.
                            'class="defaultValue" '.
                            'id="'.Printer::getText($name).'" '.
                            'name="'.Printer::getText($name).'" ' ;
        if (!$editable) {
            $inputElement .= 'disabled="disabled" ' ;
        }
        
        $inputElement .= '>' ;

        foreach ($element->getOptions() as $option) {
            $selected = '' ;
            if ((is_null($value) && $option->isSelected())
                || $option->getValue() === $value
            ) {
                $selected = 'selected="selected"' ;
            }

            $inputElement .= '<option '.
                                'value="'.Printer::getText(
                                    $option->getValue()
                                ).'" '.
                                $selected.
                             ' >'.
                                Printer::getText(
                                    LanguageManager::getInstance()->getText(
                                        $option->getValue()
                                    )
                                ).
                             '</option>' ;
        }
        $inputElement .= '</select>' ;


        return $inputElement ;
    }

    /**
     * The function that returns a form text
     *
     * @param JsonFormText $element the form text element
     *
     * @return string
     */
    public static function getText(JsonFormText $element)
    {
        $class = $element->getClassName();
        if (!isNullOrEmptyString($class)) {
            $class = ' '.$class ;
        }
        
        $style = $element->getStyle();
        if (!isNullOrEmptyString($style)) {
            $style = 'style="'.$style.'"' ;
        }

        $inputElement  = '<span class="text'.$class.'" '.$style.' >' .
                              Printer::getText(
                                  LanguageManager::getInstance()->getText(
                                      $element->getLabel()
                                  )
                              ).
                         '</span>' ;

        return $inputElement ;
    }

    /**
     * The function that returns a form title
     *
     * @param JsonFormTitle $element the form title element
     *
     * @return string
     */
    public static function getTitle(JsonFormTitle $element)
    {
        $class = $element->getClassName();
        if (!isNullOrEmptyString($class)) {
            $class = ' '.$class ;
        }
        
        $style = $element->getStyle();
        if (!isNullOrEmptyString($style)) {
            $style = 'style="'.$style.'"' ;
        }

        $inputElement  = '<span class="title'.$class.'" '.$style.' >'.
                              Printer::getText(
                                  LanguageManager::getInstance()->getText(
                                      $element->getLabel()
                                  )
                              ).
                         '</span>' ;

        return $inputElement ;
    }
    
    /**
     * The function that returns a clear-both div
     *
     * @param JsonFormElement $element the clear-both element
     *
     * @return string
     */
    public static function getClearBoth(JsonFormElement $element)
    {

        $inputElement = '<div style="clear-both"></div>' ;
        return $inputElement ;
    }

    /**
     * The function that returns an input value
     *
     * @param JsonFormInput $element the input element
     * @param mixed         $value   the value of the input
     *
     * @return string
     */
    public static function getInputValue(
        JsonFormInput $element,
        /*mixed*/ $value=null
    )
    {
        $class = $element->getClassName();
        if (!isNullOrEmptyString($class)) {
            $class = ' '.$class ;
        }
        
        $style = $element->getStyle();
        if (!isNullOrEmptyString($style)) {
            $style = 'style="'.$style.'"' ;
        }

        $strValue = '' ;
        if (!is_null($value) && is_array($value)) {
            foreach ($value as $val) {
                if ($strValue != '') {
                    $strValue .= ', ' ;
                }
                $strValue .= $val ;
            }
        } else if ($value instanceof IPrimitiveObject) {
            $strValue = $value->toString();
        } else {
            $strValue = $value ;
        } 
        
        $htmlValue = Printer::getText($strValue);
        $label  = Printer::getText(
            LanguageManager::getInstance()->getText(
                $element->getLabel()
            )
        );
        
        if (!isNullOrEmptyString($strValue)) {
            if ($element->isImage()) {
                $realPath = str_replace(getWwwDirectory().'/', '', realpath($strValue));
                $htmlValue = '<img src="'.Printer::getText($realPath).'" alt="'.$label.'" />' ;
            } else if ($element->getInputType() == 'file') {
                $htmlValue = Printer::getText(basename($strValue));
            }
        }
        
        $inputElement  = '<span class="element_item'.$class.'" '.$style.' >'.
                              '<strong>'.
                                  $label.
                              '</strong> '.
                              $htmlValue.
                         '</span>' ;

        return $inputElement ;
    }

}
